<?php

namespace ulue\core\application;

use Windwalker\Filter\Unicode;
use Windwalker\IO\Cli\IO;
use Windwalker\IO\Cli\IOInterface;
use ulue\core\utils\Configuration;

// AbstractApplication extends AbstractApplication
abstract class AbstractCliApplication extends AbstractApplication
{
    /**
     * Property io.
     * @var  IOInterface
     */
    public $io = null;

    /**
     * Property lastOutput.
     * @var  mixed
     */
    protected $lastOutput = null;

    /**
     * Property lastReturn.
     * @var  mixed
     */
    protected $lastReturn = null;

    public function __construct(IOInterface $io = null, Configuration $config=null)
    {
        // Close the application if we are not executed from the command line.
        if (!defined('STDOUT') || !defined('STDIN') || !isset($_SERVER['argv']))
        {
            $this->close();
        }

        $this->io     = $io instanceof IOInterface  ? $io     : new IO;
        $this->config = $config instanceof Configuration ? $config : new Configuration;

        $this->init();

        // Set the execution datetime and timestamp;
        $this->def('execution.datetime', gmdate('Y-m-d H:i:s'));
        $this->def('execution.timestamp', time());

        // Set the current directory.
        $this->def('cwd', getcwd());
    }

    /**
     * Exec a command.
     * @param string $command
     * @param array  $arguments
     * @param array  $options
     * @return  string
     */
    protected function exec($command, $arguments = array(), $options = array())
    {
        $arguments = implode(' ', (array) $arguments);
        $options = implode(' ', (array) $options);

        $command = sprintf('%s %s %s', $command, $arguments, $options);

        $this->out('>> ' . $command);

        /*if ($this->io->getOption('dry-run'))
        {
            return '';
        }*/

        $return = exec(trim($command), $this->lastOutput, $this->lastReturn);

        $this->out($return);
    }

    /**
     * Property returnVar.
     * @var  mixed
     */
    protected $returnVar = null;

    protected function passthru($command, $arguments = array(), $options = array())
    {
        $arguments = implode(' ', (array) $arguments);
        $options   = implode(' ', (array) $options);
        $command   = sprintf('%s %s %s', $command, $arguments, $options);

        $this->out('>> ' . $command);
        ob_start();
        passthru(trim($command), $this->lastReturn );
        $output = ob_get_clean();

        //to utf8
        // $output = Unicode\UnicodeHelper::toUnicode($output);

        $this->out($output);

        return (bool)$output;
    }

    /**
     * Write a string to standard output.
     * @param   string   $text  The text to display.
     * @param   boolean  $nl    True (default) to append a new line at the end of the output string.
     * @return  AbstractApplication  Instance of $this to allow chaining.
     */
    public function out($text = '', $nl = true)
    {
        $this->io->out($text, $nl);

        return $this;
    }

    /**
     * Get a value from standard input.
     *
     * @return  string  The input string from standard input.
     */
    public function in()
    {
        return $this->io->in();
    }

    /**
     * getIo
     * @return  IOInterface
     */
    public function getIO()
    {
        return $this->io;
    }

    /**
     * setIo
     * @param   IOInterface $io
     * @return  $this
     */
    public function setIO($io)
    {
        $this->io = $io;

        return $this;
    }
}